using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;

using MVPlan.Engine;
using MVPlan.Engine.Gases;

namespace MVPlan.Engine.Segment
{
    /// <summary> 
    /// Describes a Deco Segment, a specialisation of AbstractSegment
	/// </summary>
	[Serializable]
	public class SegmentDeco : SegmentAbstract
    {
        #region Members

        /// <summary>Maximum M-Value Gradient encountered in this segment </summary>
        private double mvMax;
        /// <summary>Gradient Factor used in this segment </summary>
        private double gfUsed;
        /// <summary>Controlling compartment of this segment </summary>
        private int controlCompartment;

        #endregion

        #region Properties

		/// <summary>
        /// Sets controlling compartment - required for Bean interface.
        /// </summary>
        [XmlIgnore()]
		virtual public int ControlCompartment
		{
			set
			{
				controlCompartment = value;
			}			
		}

		/// <summary>
        /// Sets Gradient factor used - required for Bean Interface.
        /// </summary>
        [XmlIgnore()]
		virtual public double GfUsed
		{
			set
			{
				gfUsed = value;
			}			
		}

		/// <summary>
        /// Sets Maximum M-Value Gradient for compartment - required for Bean interface.
        /// </summary>
        [XmlIgnore()]
		virtual public double MvMax
		{
			set
			{
				mvMax = value;
			}
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Constructor for objects of class SegmentDeco.
        /// </summary>
		/// <param name="depth">Depth of segment</param>
		/// <param name="time">Time of segment</param>
		/// <param name="gas">Gas object for segment</param>
		/// <param name="setpoint">Setpoint for segment, or 0 for open circuit</param>
		public SegmentDeco(double depth, double time, Gas gas, double setpoint) : base()
		{
			base.depth = depth;
			base.gas = gas;
			base.setpoint = setpoint;
			base.type = SegmentType.DECO;
			base.time = time;
			mvMax = 0;
			gfUsed = 0;
			controlCompartment = - 1;
        }

        public SegmentDeco()
        {

        }

        #endregion

        #region Methods

        /// <summary>
        /// Override GasUsed() to determine the gas used in this segment.
        /// </summary>
        /// <returns> Gas Used in litres (cuft)</returns>
        public override double GasUsed()
        {
            if (setpoint > 0)
                return (0); // No gas used for closed circuit        

            double p; // pressure

            p = (depth + Prefs.Current.PAmb) / Prefs.Current.PConversion; // Convert to pressure (atm);
            
            return (p * time * Prefs.Current.RMVDeco);
        }

        #endregion
    }
}
